package com.wxzz.elearing.user.amqp.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.wxzz.elearing.user.entity.AdminUser;
import com.wxzz.elearing.user.entity.OperationLog;
import com.wxzz.elearing.user.entity.SystemMessage;
import com.wxzz.elearing.user.mapper.AdminUserMapper;
import com.wxzz.elearing.user.mapper.OperationLogMapper;
import com.wxzz.elearing.user.service.ISystemMessageService;
import com.wxzz.elearning.common.bean.RabbitMQConfiguration;
import com.wxzz.elearning.common.constants.RabbitPool;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.dto.FeignOperationLogDto;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.utils.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class SystemMessageConsumer {

    @Autowired
    private ISystemMessageService systemMessageService;

    @Autowired
    private OperationLogMapper operationLogMapper;

    @Autowired
    private AdminUserMapper adminUserMapper;

    /**
     * 操作日志
     *
     * @param msg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = RabbitPool.DEFAULT_QUEUE)
    public void direct(String msg, Channel channel, Message message) throws IOException {
        FeignOperationLogDto feignOperationLogDto = JSONObject.parseObject(msg, FeignOperationLogDto.class);
        OperationLog operationLog = new OperationLog();
        BeanUtils.copyProperties(feignOperationLogDto, operationLog);
        AdminUser adminUser = adminUserMapper.selectById(feignOperationLogDto.getAdminUserId());
        if (adminUser != null) {
            operationLog.setPhone(adminUser.getPhone());
            operationLog.setImage(adminUser.getImage());
            operationLog.setName(adminUser.getName());
            operationLog.setEnterpriseId(adminUser.getEnterpriseId());
            operationLog.setUsername(adminUser.getUsername());
        }
        operationLogMapper.insert(operationLog);
    }

    /**
     * 站内信订阅
     *
     * @param msg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = RabbitPool.ACK_QUEUE_CALLBACK_SYSTEM_MESSAGE)
    public void processSystemMessage(String msg, Channel channel, Message message) throws IOException {
        log.info("ACK_QUEUE_CALLBACK_SYSTEM_MESSAGE 收到:{}", msg);
        try {
            SystemMessageMqDto systemMessageMqDto = JSONObject.parseObject(msg, SystemMessageMqDto.class);
            if (StringUtils.isNotBlank(systemMessageMqDto.getMessageTitle())) {
                if (systemMessageMqDto.getMessageType() == 0) {
                    if (systemMessageMqDto.getWxUserIds() != null && systemMessageMqDto.getWxUserIds().size() != 0) {
                        SystemMessage systemMessage = new SystemMessage();
                        systemMessage.setType(1);
                        systemMessage.setMessageDetail(systemMessageMqDto.getMessageDetail());
                        systemMessage.setMessageSendTime(LocalDateTime.now());
                        systemMessage.setMessageTitle(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageSubhead(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageType(systemMessageMqDto.getMessageType());
                        systemMessage.setCommonIds(systemMessageMqDto.getWxUserIds());
                        systemMessageService.saveSystemMessage(systemMessageMqDto.getEnterpriseId(), systemMessage);
                    }
                }
                if (systemMessageMqDto.getMessageType() == 1) {
                    if (systemMessageMqDto.getWxUserIds() != null && systemMessageMqDto.getWxUserIds().size() != 0) {
                        SystemMessage systemMessage = new SystemMessage();
                        systemMessage.setType(1);
                        systemMessage.setMessageDetail(systemMessageMqDto.getMessageDetail());
                        systemMessage.setMessageSendTime(LocalDateTime.now());
                        systemMessage.setMessageTitle(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageSubhead(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageType(systemMessageMqDto.getMessageType());
                        systemMessage.setCommonIds(systemMessageMqDto.getWxUserIds());
                        systemMessageService.saveSystemMessage(systemMessageMqDto.getEnterpriseId(), systemMessage);
                    }
                }
                if (systemMessageMqDto.getMessageType() == 2) {
                    if (systemMessageMqDto.getWxUserIds() != null && systemMessageMqDto.getWxUserIds().size() != 0) {
                        SystemMessage systemMessage = new SystemMessage();
                        systemMessage.setType(1);
                        systemMessage.setMessageDetail(systemMessageMqDto.getMessageDetail());
                        systemMessage.setMessageSendTime(LocalDateTime.now());
                        systemMessage.setMessageTitle(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageSubhead(systemMessageMqDto.getMessageTitle());
                        systemMessage.setMessageType(systemMessageMqDto.getMessageType());
                        systemMessage.setCommonIds(systemMessageMqDto.getWxUserIds());
                        systemMessageService.saveSystemMessage(systemMessageMqDto.getEnterpriseId(), systemMessage);
                    }
                }
            }
            log.info("ACK_QUEUE_CALLBACK_SYSTEM_MESSAGE 接受信息成功");
        } catch (Exception e) {
            e.printStackTrace();
            /**
             * 拒绝一条消息：
             * channel.basicReject(long deliveryTag, boolean requeue);
             * deliveryTag:该消息的index
             * requeue：被拒绝的是否重新入队列
             */
            //丢弃这条消息
            //Topic模式下可采用死信队列 这里先简单处理直接丢弃
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            log.error("ACK_QUEUE_CALLBACK_SYSTEM_MESSAGE 接受信息异常:{}", e.getMessage());
        }
    }

    /**
     * 短信订阅
     *
     * @param msg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = RabbitPool.ACK_QUEUE_CALLBACK_SMS)
    public void processSms(String msg, Channel channel, Message message) throws IOException {
        log.info("ACK_QUEUE_CALLBACK_SMS 收到:{}", msg);
        try {
            SystemMessageMqDto systemMessageMqDto = JSONObject.parseObject(msg, SystemMessageMqDto.class);
            if (systemMessageMqDto != null && systemMessageMqDto.getPhones() != null) {
                for (String phone : systemMessageMqDto.getPhones()) {
                    if (StringUtils.isNotBlank(phone)) {
                        SmsUtil smsUtil = new SmsUtil();
                        if (systemMessageMqDto.getSmsType() == 0) {
                            smsUtil.sendMsg(phone, systemMessageMqDto.getTemplateId(), systemMessageMqDto.getParams());
                        }
                        if (systemMessageMqDto.getSmsType() == 1) {
                            smsUtil.sendVerifyMsg(phone, systemMessageMqDto.getTemplateId(), systemMessageMqDto.getParams());
                        }
                    }
                }
            }
            log.info("ACK_QUEUE_CALLBACK_SMS 接受信息成功");
        } catch (Exception e) {
            e.printStackTrace();
            /**
             * 拒绝一条消息：
             * channel.basicReject(long deliveryTag, boolean requeue);
             * deliveryTag:该消息的index
             * requeue：被拒绝的是否重新入队列
             */
            //丢弃这条消息
            //Topic模式下可采用死信队列 这里先简单处理直接丢弃
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            log.error("ACK_QUEUE_CALLBACK_SMS 接受信息异常:{}", e.getMessage());
        }
    }

    /**
     * 公众号订阅
     *
     * @param msg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = RabbitPool.ACK_QUEUE_CALLBACK_SUBSCRIBE)
    public void processSubscribe(String msg, Channel channel, Message message) throws IOException {

    }


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @RabbitListener(queues = RabbitMQConfiguration.WXZZ_MESSAGE_DELAY_QUEUE)
    public void onDelayMessage(@Payload String msg,
                               @Headers Map<String, Object> headers,
                               Channel channel, Message message) throws IOException {
        log.info("监听延时交换机, 收到消息: {}", message);
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
            this.process(msg); // 内部处理
        } catch (Exception e) {
            boolean redelivered = (boolean) headers.get(AmqpHeaders.REDELIVERED);
            channel.basicNack(deliveryTag, false, !redelivered);
        }
    }


    private void process(String msg) {
        // log.info("livetelecastQueue 接收时间:{} 接收内容:{}", LocalDateTime.now().toString(), msg);
        JSONObject map = JSON.parseObject(msg);
        //消息唯一标识
        String uuid = redisTemplate.opsForValue().get(RedisConstants.DEAL_QUEUE_MESSAGE + map.get("id") + map.get("type"));
        //验证
        if (map.get("uuid").equals(uuid)) {
            //todo 小程序订阅
            if (RabbitMQConfiguration.QUEUE_TYPE8.equals(map.get("type"))) {
                systemMessageService.sendSms(JSONObject.parseObject(map.getString("systemMessage"), SystemMessage.class));
                log.info("服务消费-id为:{}的通知的短信发送成功", map.get("id"));
            } else {
                log.error("服务消费-id为:{}的消费类型不存在：{}", map.get("id"), map.get("type"));
            }
        } else {
            log.error("服务消费-失败：uuid不匹配：{}，{}", uuid, map.get("uuid"));
        }
    }
}
